/*
 * Copyright 2014, NuzoweR@Schneefeuer <nuzower@gmail.com>.
 * The Settlers Online - Combat Simulator (tsosim).
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef COMBATLOG_H_
#define COMBATLOG_H_

#include "Units.h"

#include <list>
#include <map>

#include "Garrison.h"

class CombatLog
{
public:

	struct UnitAttackData
	{
		UnitAttackData(const Unit* _attacker=NULL, int _att_number=0, int _damage=0, const Unit* _defender=NULL, int _def_number=0);

		const Unit* attacker;                 // name, hitpoints
		const Unit* defender;                 // name, hitpoints
		int att_unit_number, def_unit_number; // number of attackers, number of defenders (before the attack)
		int damage_dealt;                     // damage done by attacker to defender
		int def_hitpoints_left;               // hitpoints left after the attack
	};

	class GroupAttackData 
	{
	public:
		const Garrison::Group* attacker;      // name, unit names
		const Garrison::Group* defender;      // name, unit names
		int num_attacker, total_num_attacker;
		int num_defender, total_num_defender;
		int num_defender_left;
		std::list<UnitAttackData> attack_data;
	};

	struct AttackData {
		const Garrison* attacker;
		const Garrison* defender;
		std::list<GroupAttackData> attack_data;
	};

	// initiative -> attack data
	typedef std::map<int, std::list<AttackData> > AttackByInitiative_t;

	// round number -> attack by initiative
	typedef std::map<int, AttackByInitiative_t> AttackByRound_t;


	// -------------------------- // 

	AttackByRound_t Log;

	void clear();

	// -------------------------- // 

	/*  
	 */
	void start_attack(int round, int initiative, const Garrison* attacker, const Garrison* defender);

	void add_group_attack(const Garrison::Group* attacker, const Garrison::Group* defender, int num_attackers, int num_defenders);
	void finish_group_attack(int num_defenders_left);

	void add_unit_attack(const Unit* attacker, const Unit* defender, int att_num, int def_num, int damage, int def_hitpoints_left);

	// -------------------------- // 

	void print_combat_log(std::ostream& out, int log_level, bool print_braces=false);

private:

	void print_group_attack(std::ostream& out, std::list<GroupAttackData> const& lgad, int log_level, bool braces);
	void print_unit_attack (std::ostream& out, std::list<UnitAttackData> const& luad, int num_attackers, int num_defenders);

private:

	AttackData      *current_attack_data;
	GroupAttackData *current_group_attack_data;
};

#endif // COMBATLOG_H_

